﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.DataAnnotations;
using System.Windows.Input;
using System.Xml.Serialization;
using System.IO;
using ViewMaker.Core.Controls;
using ViewMaker.Core.Utils;
using System.ComponentModel;

namespace ViewMaker.Core.ViewModels
{
    [View(ViewControlType.Grid, Title = "Layout XML")]
    [ViewProperty(GridViewControl.Properties.Margin, "10")]
#if !SILVERLIGHT
    [ViewProperty(GridViewControl.Properties.WindowWidth, 600)]
    [ViewProperty(GridViewControl.Properties.WindowHeight, 300)]
#else
    [ViewProperty(GridViewControl.Properties.Width, 600)]
    [ViewProperty(GridViewControl.Properties.Height, 300)]
#endif
    [ViewProperty(GridViewControl.Properties.HeaderWidth, 100)]
    public class ViewLayoutViewerViewModel : ViewModelBase, IViewLayoutGeneratorProvider
    {
        [Display(Name = "File name")]
        [ViewProperty(TextBoxViewControl.Properties.HeaderPosition, LayoutHeaderPosition.Hidden)]
        public string Name { get; private set; }

        [View(ViewControlType.TextBox)]
        [ViewProperty(TextBoxViewControl.Properties.IsMultiline, true)]
        [ViewProperty(TextBoxViewControl.Properties.IsReadOnly, true)]
        [ViewProperty(TextBoxViewControl.Properties.HeaderPosition, LayoutHeaderPosition.Hidden)]
        [ViewProperty(TextBoxViewControl.Properties.GridHeight, "100*")]
        public string Code { get; set; }

        private ViewLayoutViewModel targetViewModel;
        private ViewLayoutItem targetLayout;

        /// <summary>
        /// ViewLayoutを保存するサービス
        /// </summary>
        protected IViewLayoutPersistenceService ViewLayoutPersistence
        {
            get { return ServiceLocator.GetService<IViewLayoutPersistenceService>(); }
        }

        public ViewLayoutViewerViewModel(ViewLayoutViewModel vm)
        {
            this.targetViewModel = vm;
            this.targetLayout = vm.Root[0];
            this.Name = ViewLayoutPersistence.GetDefaultLayoutName(vm.ViewModelType);
            this.Status = new StatusFooterViewModel();
            GenerateXml(targetLayout);
        }

        private void GenerateXml(ViewLayoutItem layout)
        {
            using (var st = new StringWriter())
            {
                var ser = new XmlSerializer(typeof(ViewLayoutItem));
                ser.Serialize(st, layout);
                Code = st.ToString();
            }
        }

        /// <summary>
        /// レイアウト情報の保存
        /// </summary>
        [Display(Name = "Save")]
        public ICommand SaveCommand
        {
            get { return CreateCommand(SaveAction); }
        }

        private void SaveAction()
        {
            ViewLayoutPersistence.Save(targetLayout, Name);
            targetViewModel.ResetLayoutData();
            OnPropertyChanged("DeleteCommand");
            Status.SetInformationMessage("Saved");
        }

        [Display(Name = "Save As")]
        public ICommand SaveAsCommand
        {
            get { return CreateCommand(SaveAsAction); }
        }

        private void SaveAsAction()
        {
            using (var st = this.ShowSaveFile("(*.xml)|*.xml"))
            {
                if (st != null)
                {
                    ViewLayoutPersistence.Serialize(targetLayout, st);
                    Status.SetInformationMessage("Saved");
                }
            }
        }
        /// <summary>
        /// レイアウト情報の読み出し
        /// </summary>
        [Display(Name = "Load")]
        public ICommand LoadCommand
        {
            get { return CreateCommand(LoadAction); }
        }

        private void LoadAction()
        {
            using (var st = this.ShowOpenFile("(*.xml)|*.xml"))
            {
                if (st != null)
                {
                    targetLayout = ViewLayoutPersistence.Deserialize(st);
                    GenerateXml(targetLayout);
                    targetViewModel.Root.Clear();
                    targetViewModel.Root.Add(targetLayout);
                }
            }
        }

        /// <summary>
        /// レイアウト情報の削除
        /// </summary>
        [Display(Name = "Delete")]
        public ICommand DeleteCommand
        {
            get { return CreateCommand((x) => DeleteAction(), (x) => ViewLayoutPersistence.Exists(Name)); }
        }

        private void DeleteAction()
        {
            if (!ViewLayoutPersistence.Exists(Name)) return;
            ViewLayoutPersistence.Delete(Name);
            OnPropertyChanged("DeleteCommand");
            Status.SetInformationMessage("Deleted");
        }

        [Display(Name = "All Layouts")]
        public ICommand ShowDataCommand { get { return CreateCommand(() => ViewUtil.ShowDialog(new ViewLayoutDataViewModel())); } }

        [Display(Name = "Close")]
        public ICommand CloseCommand { get { return CreateViewCommand(ViewCommands.Close); } }

        [Browsable(false)]
        [ViewProperty(UserControlViewControl.Properties.HeaderPosition, LayoutHeaderPosition.Hidden)]
        public StatusFooterViewModel Status { get; private set; }


        #region IViewLayoutGeneratorProvider Members

        ViewLayoutItem IViewLayoutGeneratorProvider.Generate()
        {
            var generator = ServiceLocator.GetService<IViewLayoutGenerator>();
            var layout = generator.Generate(this, LayoutGenerateFlag.LayoutData | LayoutGenerateFlag.SkipLoadError);
            if (layout != null) return layout;
            layout = generator.Generate(this, LayoutGenerateFlag.TypeInfo);

            var statusBar = layout.GenerateChild(typeof(ViewLayoutViewerViewModel), "Status");
            layout.AddChild(statusBar);
            return layout;
        }

        #endregion
    }
}
